var RoomServiceUrl = "https://liveroom.qcloud.com/weapp/live_room/",
	heart = '', // 判断心跳变量
	requestSeq = 0, // 请求id
	requestTask = [], // 请求task
	accountInfo = { // 用户信息
		userID: '', // 用户ID
		userName: '', // 用户昵称
		userAvatar: '', // 用户头像URL
		userSig: '', // IM登录凭证
		sdkAppID: '', // IM应用ID
		accountType: '0', // 账号集成类型
		accountMode: 0, //帐号模式，0-表示独立模式，1-表示托管模式
		token: '', //登录RoomService后使用的票据
		accelerateURL: '',
		pushURL: ''
	},
	roomInfo = { // 房间信息
		roomID: '', // 视频位房间ID
		roomInfo: '', // 房间名称
		mixedPlayURL: '', // 混流地址
		isCreator: false, // 是否为创建者
		pushers: [], // 当前用户信息
		isLoginIM: false, // 是否登录IM
		isJoinGroup: false, // 是否加入群
		isDestory: false, // 是否已解散
		hasJoinAnchor: false, // 是否上麦
		roomStatusCode: 0, // 房间状态
	},
	event = { // 事件
		onAnchorEnter: function() {}, // 进房通知
		onAnchorExit: function() {}, // 退房通知
		onRoomDestroy: function() {}, // 群解散通知
		onRecvRoomTextMsg: function() {}, // 消息通知
		onRequestJoinAnchor: function() {}, //大主播收到小主播连麦请求通知
		onKickoutJoinAnchor: function() {}, //小主播被踢通知
		onRecvRoomCustomMsg: function() {}, //自定义消息通知
		onSketchpadData: function() {}
	};
var requestNum = 0; // 请求数
var requestJoinCallback = null;
var bigAnchorStreamID = '';
var bigAnchorWidth = 360;
var bigAnchorHeight = 480;
var gTimeoutID = null;
var mTimeDiff = 0;

/**
 * [request 封装request请求]
 * @param {options}
 *   url: 请求接口url
 *   data: 请求参数
 *   success: 成功回调
 *   fail: 失败回调
 *   complete: 完成回调
 */
function request(options) {
	requestNum++;
	requestTask[requestSeq++] = uni.request({
		url: RoomServiceUrl + options.url + (options.params ? ('?' + formatParams(options.params) + '&') : '?') + 'userID=' + accountInfo.userID + (accountInfo.token ? '&token=' + accountInfo.token : ""),
		data: options.data || {},
		header: {
			'content-type': 'application/json'
		},
		method: 'POST',
		success: options.success || function() {},
		fail: options.fail || function() {},
		complete: options.complete || function() {
			requestNum--;
		}
	});
}

/**
 * [formatParams url encode编码]
 * @param {data}
 */
function formatParams(data) {
	var arr = [];
	for (var name in data) {
		arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
	}
	return arr.join("&");
}

/**
 * [login 初始化登录信息]
 * @param {options}
 *   data: {
 *    userID: 用户ID
 *    userSig: 用户sig
 *    sdkAppID: IM应用ID
 *    userName: 用户昵称
 *    userAvatar: 用户头像地址
 *   }
 *   success: 成功回调
 *   fail: 失败回调
 *
 * @return success
 *   userName: 用户昵称
 */
function login(options) {
	if (!options || !options.data.sdkAppID || !options.data.userID || !options.data.userSig) {
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'init参数错误'
		});
		return;
	}
	accountInfo.userID = options.data.userID;
	accountInfo.userSig = options.data.userSig;
	accountInfo.sdkAppID = options.data.sdkAppID;
	accountInfo.userName = options.data.userName;
	accountInfo.userAvatar = options.data.userAvatar;
	request({
		url: 'login',
		params: {
			sdkAppID: accountInfo.sdkAppID,
			userSig: accountInfo.userSig,
		},
		data: {},
		success: function(ret) {
			if (ret.data.code) {
				options.fail && options.fail(ret);
				return;
			}
			accountInfo.token = ret.data.token;
			accountInfo.userID = ret.data.userID;
			mTimeDiff = Math.round(Date.now()) - ret.data.timestamp;
			options.success && options.success(ret);
		},
		fail: function(err) {
			options.fail && options.fail(err);
		}
	});
}

/**
 * [logout 结束初始化信息]
 */
function logout() {
	request({
		url: "logout",
		success: function(ret) {},
		fail: function(ret) {}
	});
	accountInfo.userID = '';
	accountInfo.userSig = '';
	accountInfo.sdkAppID = '';
	accountInfo.userName = '';
	accountInfo.userAvatar = '';
	accountInfo.token = '';
}

/**
 * [mergeAnchors 合并房间信息]
 */
function mergeAnchors(options) {
	if (!roomInfo.hasJoinAnchor) {
		return;
	}
	getAnchors({
		data: {
			roomID: roomInfo.roomID
		},
		success: function(res) {
			innerMergerAnchors(res.data)
			options.success && options.success(res);
		},
		fail: function(err) {
			console.log('合并房间信息失败', err)
			options.fail && options.fail(err);
		}
	});
};

function innerMergerAnchors(data) {
	var enterPushers = [], // enterPushers：新进推流人员信息
		leavePushers = [], // leavePushers：退出推流人员信息
		ishave = 0; // ishave：用于判断去重操作
	// console.log('去重操作');
	// console.log('旧', JSON.stringify(roomInfo.pushers));
	// console.log('新', JSON.stringify(data.pushers));
	// console.log('用户信息:', JSON.stringify(accountInfo));
	data.pushers && data.pushers.forEach(function(val1) {
		ishave = 0;
		roomInfo.pushers && roomInfo.pushers.forEach(function(val2) {
			if (val1.userID == val2.userID) {
				ishave = 1;
			}
		});
		if (!ishave) {
			enterPushers.push(val1);
		}
		ishave = 0;
	});
	roomInfo.pushers && roomInfo.pushers.forEach(function(val1) {
		ishave = 0;
		data.pushers && data.pushers.forEach(function(val2) {
			if (val1.userID == val2.userID) {
				ishave = 1;
			}
		});
		if (!ishave) {
			leavePushers.push(val1);
		}
		ishave = 0;
	});
	if (data.roomStatusCode) {
		roomInfo.roomStatusCode = data.roomStatusCode
	}
	roomInfo.pushers = data.pushers;
	if (enterPushers.length) {
		console.log('有人进入房间', JSON.stringify(enterPushers));
		event.onAnchorEnter && event.onAnchorEnter({
			pushers: enterPushers
		});
		setTimeout(() => {
			mergeStream(1);
		}, 5000)
	}
	if (leavePushers.length) {
		console.log('有人退出房间', JSON.stringify(leavePushers));
		event.onAnchorExit && event.onAnchorExit({
			pushers: leavePushers
		});
		setTimeout(() => {
			mergeStream(1);
		}, 5000)
	}
}

/**
 * [getAnchors 获取房间信息]
 * @param {object}
 */
function getAnchors(object) {
	var data = {};
	if (object.data && object.data.roomID) {
		data.roomID = object.data.roomID;
	} else if (roomInfo.roomID) {
		data.roomID = roomInfo.roomID;
	} else {
		object.fail && object.fail({
			errCode: -999,
			errMsg: '无roomID'
		})
		return;
	}
	request({
		url: 'get_anchors',
		data: data,
		success: function(ret) {
			if (ret.data.code) {
				console.log('请求CGI:get_anchors失败', ret);
				object.fail && object.fail({
					errCode: ret.data.code,
					errMsg: '请求CGI:get_anchors失败:' + ret.data.message +'[' + ret.data.code + ']'
				});
				return;
			}
			object.success && object.success(ret);
		},
		fail: object.fail
	});
}

/**
 * [pusherHeartBeat 推流者心跳]
 * @param {options}
 */
function pusherHeartBeat(options) {
	if (options) {
		setTimeout(function() {
			proto_pusherHeartBeat();
		}, 3000);
	}
	if (heart) {
		setTimeout(function() {
			proto_pusherHeartBeat();
			pusherHeartBeat();
		}, 7000);
	}
}

/**
 * [proto_pusherHeartBeat 心跳请求]
 * @param {options}
 */
function proto_pusherHeartBeat() {
	request({
		url: 'anchor_heartbeat',
		data: {
			roomID: roomInfo.roomID,
			userID: accountInfo.userID,
			roomStatusCode: roomInfo.roomStatusCode
		},
		success: function(ret) {
			if (ret.data.code) {
				console.log('心跳失败：', ret);
				// event.onAnchorExit && event.onAnchorExit({
				// 	type: 'dismiss',
				// 	pushers: []
				// });
				return;
			}
			if (ret.data.pushers) {
				innerMergerAnchors(ret.data);
			}
		},
		fail: function(err) {
			console.log('心跳失败：', err);
		}
	});
}

/**
 * [stopPusherHeartBeat 停止推流者心跳]
 */
function stopPusherHeartBeat() {
	heart = false;
}

/**
 * [getRoomList 获取房间列表]
 * @param {options}
 *   data: {
 *   	index: 获取的房间开始索引，从0开始计算
 *   	cnt: 获取的房间个数
 *   }
 *   success: 成功回调
 *   fail: 失败回调
 *
 * @return success
 *   rooms: 房间列表信息
 */
function getRoomList(options) {
	if (!options) {
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'getRoomList参数错误'
		});
		return;
	}
	request({
		url: 'get_room_list',
		data: {
			index: options.data.index || 0,
			cnt: options.data.cnt || 20
		},
		success: function(ret) {
			if (ret.data.code) {
				console.error('获取房间列表失败: ', ret);
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			console.log("房间列表信息:", ret);
			options.success && options.success({
				rooms: ret.data.rooms
			});
		},
		fail: function(err) {
			console.log('获取房间列表失败: ', err);
			if (err.errMsg == 'request:fail timeout') {
				var errCode = -1;
				var errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode || -1,
				errMsg: errMsg || '获取房间列表失败'
			});
		}
	});
}


/**
 * [getPushURL 获取推流地址]
 * @param {options}
 *   success: 成功回调
 *   fail: 失败回调
 *
 * @return success
 *   pushURL: 推流地址
 */
function getPushURL(options) {
	if (!options) {
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'getPushURL参数错误'
		});
		return;
	}
	request({
		url: 'get_anchor_url',
		data: {
			userID: accountInfo.userID
		},
		success: function(ret) {
			if (ret.data.code) {
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message
				});
				return;
			}
			options.success && options.success({
				accelerateURL: ret.data.accelerateURL,
				pushURL: ret.data.pushURL
			});
		},
		fail: function(err) {
			if (err.errMsg == 'request:fail timeout') {
				var errCode = -1;
				var errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode || -1,
				errMsg: errMsg || '获取推流地址失败'
			});
		}
	});
};


/**
 * [setListener 设置监听事件]
 * @param {options}
 *   onRoomDestroy: 群解散通知
 *   onRecvRoomTextMsg: 消息通知
 */
function setListener(options) {
	event.onAnchorEnter = options.onAnchorEnter || function() {};
	event.onAnchorExit = options.onAnchorExit || function() {};
	event.onRoomDestroy = options.onRoomDestroy || function() {};
	event.onRecvRoomTextMsg = options.onRecvRoomTextMsg || function() {};
	event.onRequestJoinAnchor = options.onRequestJoinAnchor || function() {};
	event.onKickoutJoinAnchor = options.onKickoutJoinAnchor || function() {};
	event.onRecvRoomCustomMsg = options.onRecvRoomCustomMsg || function() {};
	event.onSketchpadData = options.onSketchpadData || function() {};
}

/**
 * [createRoom 创建房间]
 * @param {options}
 *   data: {
 *   	roomInfo: 房间名称
 *    pushURL: 推流地址
 *   }
 *   success: 成功回调
 *   fail: 失败回调
 */
function createRoom(options) {
	// if (roomInfo.isDestory) {
	// 	roomInfo.isDestory = false;
	// 	destoryRoom({});
	// 	return;
	// }
	roomInfo.isCreator = true;
	if (!options || !options.data.roomInfo) {
		console.log('createRoom参数错误', options);
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'createRoom参数错误'
		});
		return;
	}
	roomInfo.roomInfo = options.data.roomInfo;
	proto_createRoom(options);
}

function proto_createRoom(options) {
	var createRoomInfo = {
		userID: accountInfo.userID,
		roomInfo: roomInfo.roomInfo
	};
	if (options.data.roomID && options.data.roomID.length > 0) {
		createRoomInfo.roomID = options.data.roomID;
	}
	request({
		url: 'create_room',
		data: createRoomInfo,
		success: function(ret) {
			if (ret.data.code) {
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			roomInfo.roomID = ret.data.roomID;
			roomInfo.roomCreator = accountInfo.userID;
			options.success && options.success(ret);
		},
		fail: function(err) {
			if (err.errMsg == 'request:fail timeout') {
				var errCode = -1;
				var errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode || -3,
				errMsg: errMsg || '创建房间失败'
			});
		}
	});
}

/**
 * [joinAnchor 加入推流]
 * @param {options}
 *   data: {
 *   	roomID: 房间ID
 *   	pushURL: 推流地址
 *   }
 *   success: 成功回调
 *   fail: 失败回调
 */
function joinAnchor(options) {
	if (!options || !options.data.roomID || !options.data.pushURL) {
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'joinAnchor参数错误'
		});
		return;
	}
	roomInfo.roomID = options.data.roomID;
	roomInfo.isDestory = false;
	proto_joinAnchor(options);
}

function proto_joinAnchor(options) {
	request({
		url: 'add_anchor',
		data: {
			roomID: roomInfo.roomID,
			userID: accountInfo.userID,
			userName: accountInfo.userName,
			userAvatar: accountInfo.userAvatar,
			pushURL: options.data.pushURL
		},
		success: function(ret) {
			if (ret.data.code) {
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			roomInfo.hasJoinAnchor = true;
			mergeAnchors(options);
			// if (options.data.type == 'public') {
				
			// }
			// 开始心跳
			heart = true;
			pusherHeartBeat(1);
		},
		fail: function(err) {
			if (err.errMsg == 'request:fail timeout') {
				var errCode = -1;
				var errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode || -4,
				errMsg: errMsg || '上麦失败'
			});
		}
	});
}

/**
 * [enterRoom 进入房间]
 * @param {options}
 *   data: {
 *   	roomID: 房间ID
 *   }
 *   success: 成功回调
 *   fail: 失败回调
 */
function enterRoom(options) {
	roomInfo.isCreator = false;
	roomInfo.isJoinGroup = false;
	if (!options || !options.data.roomID) {
		options.fail && options.fail({
			errCode: -9,
			errMsg: 'enterRoom参数错误'
		});
		return;
	}
	roomInfo.roomID = options.data.roomID;
	var userInfo = {
		userID: accountInfo.userID,
		userName: accountInfo.userName,
		userAvatar: accountInfo.userAvatar,
		userSex: options.data.userSex
	}
	addAudience({
		data: {
			roomID: options.data.roomID,
			userID: accountInfo.userID,
			userInfo: JSON.stringify(userInfo)
		},
		success: function(ret) {
			getAnchors({
				data: {
					roomID: roomInfo.roomID
				},
				success: function(ret) {
					roomInfo.roomID = ret.data.roomID;
					roomInfo.roomInfo = ret.data.roomInfo;
					roomInfo.roomCreator = ret.data.roomCreator;
					roomInfo.mixedPlayURL = ret.data.mixedPlayURL;
					options.success && options.success(ret);
				},
				fail: function(ret) {
					options.fail && options.fail({
						errCode: ret.errCode,
						errMsg: ret.errMsg || '拉取主播信息失败'
					});
				}
			});
		},
		fail: function(err) {
			options.fail && options.fail({
				errCode: err.errCode,
				errMsg: err.errMsg || '观众进房失败'
			});
		}
	})
}

/**
 * [clearRequest 中断请求]
 * @param {options}
 */
function clearRequest() {
	for (var i = 0; i < requestSeq; i++) {
		requestTask[i].abort();
	}
	requestTask = [];
	requestSeq = 0;
}

/**
 * [exitRoom 退出房间]
 * @param {options}
 */
function exitRoom(options) {
	if (roomInfo.isCreator) {
		destoryRoom(options);
	} else {
		leaveRoom(options);
	}
	roomInfo.isDestory = true;
	roomInfo.roomID = '';
	roomInfo.pushers = [];
	roomInfo.mixedPlayURL = "";
	roomInfo.roomInfo = "";
	accountInfo.pushURL = "";
	accountInfo.isCreator = false;
}

/**
 * [leaveRoom 退出房间]
 */
function leaveRoom(options) {
	if (!roomInfo.hasJoinAnchor) {
		delAudience({
			data: {
				userID: accountInfo.userID,
				roomID: roomInfo.roomID
			},
			success: options.success,
			fail: options.fail
		})
		return;
	}
	// 停止心跳
	stopPusherHeartBeat();
	request({
		url: 'delete_anchor',
		data: {
			roomID: roomInfo.roomID,
			userID: accountInfo.userID
		},
		success: function(ret) {
			if (ret.data.code) {
				console.error('退出推流失败: roomID:' + roomInfo.roomID + ", userID:" + accountInfo.userID);
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			roomInfo.hasJoinAnchor = false;
			options.success && options.success({});
		},
		fail: function(err) {
			var errCode = err.errCode || -1;
			var errMsg = err.errMsg || '退出房间失败'
			if (err.errMsg == 'request:fail timeout') {
				errCode = -1;
				errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode,
				errMsg: errMsg
			});
		}
	});

}

/**
 * [destoryRoom 销毁房间]
 */
function destoryRoom(options) {
	// 停止心跳
	stopPusherHeartBeat();
	// clearRequest();
	roomInfo.isJoinGroup && webimhandler.destroyGroup();
	if (roomInfo.isDestory) return;
	request({
		url: 'destroy_room',
		data: {
			roomID: roomInfo.roomID,
			userID: accountInfo.userID
		},
		success: function(ret) {
			if (ret.data.code) {
				console.log('关闭房间失败:', ret);
				console.error('关闭房间失败: roomID:' + roomInfo.roomID + ", userID:" + accountInfo.userID);
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			console.log('关闭房间成功');
			options.success && options.success({});
		},
		fail: function(err) {
			console.log('关闭房间失败:', err);
			var errCode = err.errCode || -1;
			var errMsg = err.errMsg || '关闭房间失败'
			if (err.errMsg == 'request:fail timeout') {
				errCode = -1;
				errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode,
				errMsg: errMsg
			});
		}
	});
}

function quitJoinAnchor(options) {
	stopPusherHeartBeat();
	request({
		url: 'delete_anchor',
		data: {
			roomID: roomInfo.roomID,
			userID: accountInfo.userID
		},
		success: function(ret) {
			if (ret.data.code) {
				console.log('退出推流失败:', ret);
				options.fail && options.fail({
					errCode: ret.data.code,
					errMsg: ret.data.message + '[' + ret.data.code + ']'
				});
				return;
			}
			console.log('退出推流成功');
			roomInfo.pushers = [];
			//通知房间内其他主播
			// notifyPusherChange();
			options.success && options.success({});
		},
		fail: function(ret) {
			console.log('退出推流失败:', ret);
			if (ret.errMsg == 'request:fail timeout') {
				var errCode = -1;
				var errMsg = '网络请求超时，请检查网络状态';
			}
			options.fail && options.fail({
				errCode: errCode || -1,
				errMsg: errMsg || '退出房间失败'
			});
		}
	});
	roomInfo.hasJoinAnchor = false;
}

function requestJoinAnchor(object) {
	var body = {
		cmd: 'linkmic',
		data: {
			type: 'request',
			roomID: roomInfo.roomID,
			userID: accountInfo.userID,
			userName: accountInfo.userName,
			userAvatar: accountInfo.userAvatar,
			timestamp: Math.round(Date.now()) - mTimeDiff
		}
	}

	requestJoinCallback = function(ret) {
		if (gTimeoutID) {
			clearTimeout(gTimeoutID);
			gTimeoutID = null;
		}
		if (ret.errCode) {
			object.fail && object.fail(ret);
		} else {
			object.success && object.success(ret);
		}
	}

	var isTimeout = false;
	gTimeoutID = setTimeout(function() {
		gTimeoutID = null;
		console.error('申请连麦超时:', JSON.stringify(object.data));
		isTimeout = true;
		requestJoinCallback && requestJoinCallback({
			errCode: -999,
			errMsg: '申请加入连麦超时'
		});
	}, (object.data && object.data.timeout) ? object.data.timeout : 30000);

	var msg = {
		data: JSON.stringify(body)
	}
	webimhandler.sendC2CCustomMsg(roomInfo.roomCreator, msg, function(ret) {
		if (isTimeout) {
			return;
		}
		if (ret && ret.errCode) {
			console.log('请求连麦失败:', JSON.stringify(ret));
			requestJoinCallback && requestJoinCallback(ret);
			return;
		}
	});
}

function acceptJoinAnchor(object) {
	var body = {
		cmd: 'linkmic',
		data: {
			type: 'response',
			result: 'accept',
			reason: '',
			roomID: roomInfo.roomID,
			timestamp: Math.round(Date.now()) - mTimeDiff
		}
	}

	var msg = {
		data: JSON.stringify(body)
	}
	webimhandler.sendC2CCustomMsg(object.data.userID, msg, function(ret) {});
}

function rejectJoinAnchor(object) {
	var body = {
		cmd: 'linkmic',
		data: {
			type: 'response',
			result: 'reject',
			reason: object.data.reason || '主播拒绝了您的连麦请求',
			roomID: roomInfo.roomID,
			timestamp: Math.round(Date.now()) - mTimeDiff
		}
	}

	var msg = {
		data: JSON.stringify(body)
	}
	webimhandler.sendC2CCustomMsg(object.data.userID, msg, function(ret) {});
}

function kickoutJoinAnchor(object) {
	var body = {
		cmd: 'linkmic',
		data: {
			type: 'kickout',
			roomID: roomInfo.roomID,
			timestamp: Math.round(Date.now()) - mTimeDiff
		}
	}

	var msg = {
		data: JSON.stringify(body)
	}
	webimhandler.sendC2CCustomMsg(object.data.userID, msg, function(ret) {
		if (ret && ret.errCode == 0) {
			object.success && object.success(ret);
		} else {
			object.fail && object.fail(ret);
		}
	});
}

function getAccountInfo() {
	return accountInfo;
}

/**
 * 
 * @param {Int} retryCount
 */
function mergeStream(retryCount) {
	if (accountInfo.userID != roomInfo.roomCreator) {
		//大主播才能混流
		return;
	}
	var mergeStreams = [];
	if (roomInfo.pushers && roomInfo.pushers.length > 0) {
		roomInfo.pushers.forEach(function(val) {
			if (val.userID != roomInfo.roomCreator) {
				//获取流id
				var streamID = getStreamIDByStreamUrl(val.accelerateURL);
				if (streamID) {
					mergeStreams.push({
						userID: val.userID,
						streamID: streamID,
					});
				}
			} else {
				bigAnchorStreamID = getStreamIDByStreamUrl(val.accelerateURL);
			}
		});
	}
	sendStreamMergeRequest(retryCount, mergeStreams);
}

function getStreamIDByStreamUrl(streamUrl) {
	if (!streamUrl) {
		return null;
	}
	//推流地址格式: rtmp://8888.livepush.myqcloud.com/path/8888_test_12345?txSecret=aaa&txTime=bbb
	//拉流地址格式: rtmp://8888.livepush.myqcloud.com/path/8888_test_12345
	//             http://8888.livepush.myqcloud.com/path/8888_test_12345.flv
	//             http://8888.livepush.myqcloud.com/path/8888_test_12345.m3u8
	var subStr = streamUrl;
	var index = subStr.indexOf('?');
	if (index >= 0) {
		subStr = subStr.substring(0, index);
	}
	if (!subStr) {
		return null;
	}
	index = subStr.lastIndexOf('/');
	if (index >= 0) {
		subStr = subStr.substring(index + 1);
	}
	if (!subStr) {
		return null;
	}
	index = subStr.indexOf('.');
	if (index >= 0) {
		subStr = subStr.substring(0, index);
	}
	if (!subStr) {
		return null;
	}
	return subStr;
}

function sendStreamMergeRequest(retryCount, mergeStreams) {
	if (retryCount < 0) {
		return;
	}

	var mergeInfo = createMergeInfo(mergeStreams);
	console.log('混流参数信息:', JSON.stringify(mergeInfo));

	doMergeRequest(mergeInfo, function(ret) {
		if (ret) {
			// console.log('混流成功');
		} else {
			setTimeout(() => {
				retryCount--;
				sendStreamMergeRequest(retryCount, mergeStreams);
			}, 2000);
		}
	});
}

function doMergeRequest(mergeInfo, callback) {
	request({
		url: 'merge_stream',
		data: {
			userID: accountInfo.userID,
			roomID: roomInfo.roomID,
			mergeParams: JSON.stringify(mergeInfo)
		},
		success: function(ret) {
			if (ret.data.code || ret.data.merge_code) {
				console.error('混流失败:', JSON.stringify(ret));
				callback(false);
				return;
			}
			callback(true);
		},
		fail: function(ret) {
			callback(false);
		}
	})
}

function createMergeInfo(mergeStreams) {
	//组装混流JSON结构体
	var streamInfoArray = [];
	// 画布
	streamInfoArray.push({
		input_stream_id: 'canvas1',
		layout_params: {
			image_layer: 1,
			image_width: 1080,
			image_height: 1080,
			input_type: 3,
			color: '0x2e185b'
		}
	});
	//大主播
	streamInfoArray.push({
		input_stream_id: bigAnchorStreamID || '',
		layout_params: {
			image_layer: 2,
			image_width: 540,
			image_height: 540,
			location_x: 270,
			location_y: 0
		},
		crop_params: {
			crop_width: 540,
			crop_height: 540,
			crop_x: 0,
			crop_y: 0
		}
	})
	//小主播
	if (mergeStreams && mergeStreams.length > 0) {
		var layerIndex = 1
		mergeStreams.forEach(function(val) {
			if (layerIndex == 1) {
				var smallAchorInfo = {
					input_stream_id: val.streamID,
					layout_params: {
						image_layer: layerIndex + 2,
						image_width: 540,
						image_height: 540,
						location_x: 0,
						location_y: 540
					},
					crop_params: {
						crop_width: 540,
						crop_height: 540,
						crop_x: 0,
						crop_y: 0
					}
				}
			}
			if (layerIndex == 2) {
				var smallAchorInfo = {
					input_stream_id: val.streamID,
					layout_params: {
						image_layer: layerIndex + 2,
						image_width: 540,
						image_height: 540,
						location_x: 540,
						location_y: 540
					},
					crop_params: {
						crop_width: 540,
						crop_height: 540,
						crop_x: 0,
						crop_y: 0
					}
				}
			}
			streamInfoArray.push(smallAchorInfo);
			layerIndex++;
		});
	}

	var para = {
		app_id: accountInfo.sdkAppID.toString(),
		interface: 'mix_streamv2.start_mix_stream_advanced',
		mix_stream_session_id: accountInfo.sdkAppID.toString() + '_r' + roomInfo.roomID,
		output_stream_id: accountInfo.sdkAppID.toString() + '_r' + roomInfo.roomID,
		output_stream_type: 1,
		input_stream_list: streamInfoArray
	}

	var interfaceObj = {
		interfaceName: 'Mix_StreamV2',
		para: para
	}

	var reqParam = {
		timestamp: Math.round((Date.now() / 1000)),
		eventId: Math.round((Date.now() / 1000)),
		interface: interfaceObj
	}

	return reqParam;
}

function setVideoRatio(ratio) {
	if (ratio == 1) {
		//9:16
		bigAnchorWidth = 360;
		bigAnchorHeight = 640;
	} else {
		//3:4
		bigAnchorWidth = 480;
		bigAnchorHeight = 640;
	}
}

function sendC2CCustomMsg(object) {
	var body = {
		cmd: object.cmd,
		data: {
			userID: accountInfo.userID,
			userName: accountInfo.userName,
			userAvatar: accountInfo.userAvatar,
			msg: object.msg || ''
		}
	}
	var msg = {
		data: JSON.stringify(body)
	}
	webimhandler.sendC2CCustomMsg(object.toUserID ? object.toUserID : roomInfo.roomCreator, msg, function(ret) {
		if (ret && ret.errCode) {
			console.log('请求连麦失败:', JSON.stringify(ret));
			object.fail && object.fail(ret);
			return;
		}
		object.success && object.success({});
	});
}

//观众进房时，向后台发送进房通知
function addAudience(object) {
	request({
		url: 'add_audience',
		data: {
			userID: accountInfo.userID,
			roomID: object.data.roomID,
			userInfo: object.data.userInfo
		},
		success: function(ret) {
			if (ret.data.code) {
				console.log('观众进房失败', ret);
				object.fail && object.fail({
					errCode: ret.data.code,
					errMsg: '观众进房失败:' + ret.data.message + +'[' + ret.data.code + ']'
				});
				return;
			}
			object.success && object.success(ret);
		},
		fail: object.fail
	});
}

//观众退房时，向后台发送退房通知
function delAudience(object) {
	request({
		url: 'delete_audience',
		data: {
			userID: object.data.userID,
			roomID: object.data.roomID
		},
		success: function(ret) {
			if (ret.data.code) {
				console.log('减少观众请求失败', ret);
				object.fail && object.fail({
					errCode: ret.data.code,
					errMsg: '减少观众请求失败:' + ret.data.message + +'[' + ret.data.code + ']'
				});
				return;
			}
			object.success && object.success(ret);
		},
		fail: object.fail
	});
}

/**
 * 对外暴露函数
 * @type {Object}
 */
module.exports = {
	login: login, // 初始化
	logout: logout, // 结束初始化
	getRoomList: getRoomList, // 拉取房间列表
	getPushURL: getPushURL, // 拉取推流地址
	createRoom: createRoom, // 创建房间
	enterRoom: enterRoom, // 加入房间
	exitRoom: exitRoom, // 退出房间
	setListener: setListener, // 设置监听事件
	joinAnchor: joinAnchor, //加入连麦
	quitJoinAnchor: quitJoinAnchor, //退出连麦
	requestJoinAnchor: requestJoinAnchor,
	acceptJoinAnchor: acceptJoinAnchor,
	rejectJoinAnchor: rejectJoinAnchor,
	kickoutJoinAnchor: kickoutJoinAnchor,
	getAccountInfo: getAccountInfo,
	setVideoRatio: setVideoRatio,
	sendC2CCustomMsg: sendC2CCustomMsg,
	getAnchors: getAnchors
	// addRemoteView: addRemoteView,
	// deleteRemoteView: deleteRemoteView
}
